﻿using BCCommon;
using BCCommon.Enums;
using BCData.TMS.HealthReport;
using BCDto.TMS.HealthReport;
using BCEntity.TMS.HealthReport;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.HealthReport
{
    public class HealthReportService : IHealthReportService
    {
        private readonly IHealthReportData healthReportData;

        public HealthReportService(IHealthReportData healthReportData)
        {
            this.healthReportData = healthReportData;
        }

        public HealthReportDto Create(HealthReportRequestDto healthReportRequestDto, long personId, long? userId, string userName, RoleType role, long? companyId)
        {
            if (healthReportRequestDto.Temperature == 0)
            {
                throw new ArgumentException("体温不能为0");
            }
            if (string.IsNullOrWhiteSpace(healthReportRequestDto.TemperaturePhoto))
            {
                throw new ArgumentException("体温计图片不能为空");
            }
            HealthReportEntity entity = new HealthReportEntity()
            {
                IsFever = healthReportRequestDto.IsFever,
                IsCoughs = healthReportRequestDto.IsCoughs,
                DiscomfortContent = healthReportRequestDto.DiscomfortContent,
                UserName = userName,
                Role = role,
                Temperature = healthReportRequestDto.Temperature,
                TemperaturePhoto = healthReportRequestDto.TemperaturePhoto,
                CompanyId = companyId ?? 0
            };
            if (role == RoleType.Admin)
            {
                entity.AdminId = personId;
            }
            else if (role == RoleType.Driver)
            {
                entity.DriverId = personId;
            }
            if (healthReportRequestDto.TotalCholesterol.HasValue)
            {
                entity.TotalCholesterol = healthReportRequestDto.TotalCholesterol.Value;
            }
            if (healthReportRequestDto.Triglyceride.HasValue)
            {
                entity.Triglyceride = healthReportRequestDto.Triglyceride.Value;
            }
            if (healthReportRequestDto.HighDensityLipoprotein.HasValue)
            {
                entity.HighDensityLipoprotein = healthReportRequestDto.HighDensityLipoprotein.Value;
            }
            if (healthReportRequestDto.LDL.HasValue)
            {
                entity.LDL = healthReportRequestDto.LDL.Value;
            }
            if (healthReportRequestDto.SystolicPressure.HasValue)
            {
                entity.SystolicPressure = healthReportRequestDto.SystolicPressure.Value;
            }
            if (healthReportRequestDto.DiastolicPressure.HasValue)
            {
                entity.DiastolicPressure = healthReportRequestDto.DiastolicPressure.Value;
            }
            if (healthReportRequestDto.BloodGlucose.HasValue)
            {
                entity.BloodGlucose = healthReportRequestDto.BloodGlucose.Value;
            }
            if (healthReportRequestDto.HeartBeat.HasValue)
            {
                entity.HeartBeat = healthReportRequestDto.HeartBeat.Value;
            }
            if (healthReportRequestDto.Height.HasValue)
            {
                entity.Height = healthReportRequestDto.Height;
            }
            if (healthReportRequestDto.Weight.HasValue)
            {
                entity.Weight = healthReportRequestDto.Weight.Value;
            }
            var result = this.healthReportData.CreateAsync(entity).GetAwaiter().GetResult();
            return result.As<HealthReportDto>();
        }

        public HealthReportAnalysisViewDto GetAnalysisList(int? timeSpan)
        {
            List<HealthReportAnalysisDto> data = new List<HealthReportAnalysisDto>();
            DateTime time = DateTime.Now;
            for (int i = timeSpan.Value - 1; i >= 0; i--)
            {
                string timeString = time.AddDays(-i).ToString("yyyy-MM-dd");
                data.Add(new HealthReportAnalysisDto()
                {
                    ReportDate = timeString,
                    DriverRole = RoleType.Driver,
                    AdminRole = RoleType.Admin
                });
            }
            var result = this.healthReportData.GetListByDays(timeSpan).GetAwaiter().GetResult();
            foreach (var item in data)
            {
                if (result.Any(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate))
                {
                    item.AdminFeverCount = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate && p.IsFever == true && p.Role == RoleType.Admin).GroupBy(p => new { p.AdminId }).ToList().Count;
                    item.AdminCoughsCount = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate && p.IsCoughs == true && p.Role == RoleType.Admin).GroupBy(p => new { p.AdminId }).ToList().Count;
                    item.AdminDiscomfortCount = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate && p.IsDiscomfort == true && p.Role == RoleType.Admin).GroupBy(p => new { p.AdminId }).ToList().Count;
                    item.DriverFeverCount = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate && p.IsFever == true && p.Role == RoleType.Driver).GroupBy(p => new { p.UserId }).ToList().Count;
                    item.DriverCoughsCount = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate && p.IsCoughs == true && p.Role == RoleType.Driver).GroupBy(p => new { p.UserId }).ToList().Count;
                    item.DriverDiscomfortCount = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate && p.IsDiscomfort == true && p.Role == RoleType.Driver).GroupBy(p => new { p.UserId }).ToList().Count;
                    item.FeverCount = item.AdminFeverCount + item.DriverFeverCount;
                    item.CoughsCount = item.AdminCoughsCount + item.DriverCoughsCount;
                    item.DiscomfortCount = item.AdminDiscomfortCount + item.DriverDiscomfortCount;
                }
            }
            var feverAllCount = result.Where(p => p.IsFever == true).GroupBy(p => new { p.AdminId, p.UserId }).ToList().Count;
            var coughsAllCount = result.Where(p => p.IsCoughs == true).GroupBy(p => new { p.AdminId, p.UserId }).ToList().Count;
            var discomfortAllCount = result.Where(p => p.IsDiscomfort == true).GroupBy(p => new { p.AdminId, p.UserId }).ToList().Count;
            HealthReportAnalysisViewDto healthReportAnalysisViewDto = new HealthReportAnalysisViewDto()
            {
                HealthReportAnalysisDtos = data,
                FeverAllCount = feverAllCount,
                CoughsCount = coughsAllCount,
                DiscomfortAllCount = discomfortAllCount
            };
            return healthReportAnalysisViewDto;
        }

        public IEnumerable<HealthReportUserDto> GetAnalysisUserList(int? timeSpan, RoleType role, long userId)
        {
            List<HealthReportUserDto> data = new List<HealthReportUserDto>();
            DateTime time = DateTime.Now;
            for (int i = timeSpan.Value - 1; i >= 0; i--)
            {
                string timeString = time.AddDays(-i).ToString("yyyy-MM-dd");
                data.Add(new HealthReportUserDto()
                {
                    ReportDate = timeString
                });
            }
            var result = this.healthReportData.GetAnalysisUserListAsync(timeSpan, role, userId).GetAwaiter().GetResult();
            foreach (var item in data)
            {
                if (result.Any(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate))
                {
                    item.Temperature = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate).Max(p => p.Temperature);
                    var firstData = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate).OrderBy(s => s.HealthReportId).FirstOrDefault();
                    var lastData = result.Where(p => p.ReportDate.ToString("yyyy-MM-dd") == item.ReportDate).OrderByDescending(s => s.HealthReportId).FirstOrDefault();
                    if (firstData == null)
                    {
                        item.FeverCount = 0;
                        item.CoughsCount = 0;
                        item.DiscomfortCount = 0;
                        continue;
                    }
                    else
                    {
                        if (firstData.IsFever)
                        {
                            item.FeverCount = 50;
                        }
                        if (firstData.IsCoughs)
                        {
                            item.CoughsCount = 50;
                        }
                        if (firstData.IsDiscomfort)
                        {
                            item.DiscomfortCount = 50;
                        }
                    }
                    if (lastData == null)
                    {
                        item.FeverCount += item.FeverCount;
                        item.CoughsCount += item.CoughsCount;
                        item.DiscomfortCount += item.DiscomfortCount;
                    }
                    else
                    {
                        if (lastData.IsFever)
                        {
                            item.FeverCount = 50 + item.FeverCount;
                        }
                        if (lastData.IsCoughs)
                        {
                            item.CoughsCount = 50 + item.CoughsCount;
                        }
                        if (lastData.IsDiscomfort)
                        {
                            item.DiscomfortCount = 50 + item.DiscomfortCount;
                        }
                    }
                }
            }
            return data;
        }

        public PageableList<HealthReportDto> GetList(long? companyId, DateTime? start, DateTime? end, bool? ascending, int? index, int? size, long? userId, RoleType? role, bool? isFever, bool? isCoughs)
        {
            var (list, dataCount) = this.healthReportData.GetListAsync(companyId, start, end, ascending, index, size, userId, role, isFever, isCoughs).GetAwaiter().GetResult();
            return new PageableList<HealthReportDto>()
            {
                Count = dataCount,
                Items = list.As<List<HealthReportDto>>(),
                PageIndex = index.Value,
                PageSize = size.Value,
                ServerTime = DateTime.Now
            };
        }
    }
}
